package com.apexedu.eas.thread;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.apexedu.eas.entity.TAopLog;
import com.apexedu.eas.entity.TSqlLog;
import com.apexedu.eas.util.LittleTimer;
import com.apexedu.framework.util.ConfigUtil;

import oracle.net.aso.l;

public class LogConsumer implements Runnable {
	private static Logger logger = LoggerFactory.getLogger(LogConsumer.class);

	private Session sess = null;
	
	private SessionFactory sessFactory = null;
	
	// 保存日志 时间间隔
	public static int timeout = 1000 * 60 * 1;  //1分钟保存一次
	
	public static int queueSize = 2500;
	
	static{
		String time=null;
		String size =null; 
		try {
			time=ConfigUtil.getString("aop_log_timeout");
			size = ConfigUtil.getString("aop_queue_size");
		} catch (Exception e) {
			logger.error("在配置文件：config.properties中获取属性出现错误，将使用默认值");
		}
		if(time==null)
			logger.error("在配置文件中找不到 aop_log_timeout ");
		else
			timeout*= Integer.parseInt(time);
		if(size==null)
			logger.error("在配置文件中找不到 aop_queue_size ");
		else
			queueSize = Integer.parseInt(size);
		
		
	}
	
	public static BlockingQueue<TSqlLog> sqlLogQueue = new LinkedBlockingQueue<TSqlLog>(queueSize); // sql执行记录队列

	public static BlockingQueue<TAopLog> ctrlLogQueue = new LinkedBlockingQueue<TAopLog>(queueSize); // 控制层访问记录队列

	
	public LogConsumer(SessionFactory sessionFactory) {
		this.sessFactory = sessionFactory;
		//this.sess = sessionFactory.openSession();
	}

	@Override
	public void run() {
		// 消费者
		LittleTimer timer = new LittleTimer(); // 计时器
		Transaction tran = null;
		for (;;) {
			try {
				logger.info("正在查找需要保存的日志");
				if (ctrlLogQueue.size() > 0 || sqlLogQueue.size() > 0) {
					timer.start();
					List<TAopLog> aop = new LinkedList<TAopLog>();
					List<TSqlLog> sql = new LinkedList<TSqlLog>();
					logger.debug("从ctrlLogQueue队列中获取到{}条数据", ctrlLogQueue.drainTo(aop));
					logger.debug("从sqlLogQueue队列中获取到{}条数据", sqlLogQueue.drainTo(sql));
					sess=sessFactory.openSession();
					tran = sess.beginTransaction();
					for (TAopLog log : aop) {
						sess.save(log);
					}
					for (TSqlLog log : sql) {
						sess.save(log);
					}
					// if(sess.getTransaction().isActive())
					tran.commit();
					logger.debug("数据保存完成，总数量：{} , 共耗时：{}ms ", sql.size() + aop.size(), timer.end());
				}
				
			} catch (Exception e) {
				logger.error("save TAopLog error : ", e);
			} finally {
				if(sess!=null && sess.isOpen()){
					sess.flush();
					sess.close();
				}
				try {
					Thread.sleep(timeout);
				} catch (InterruptedException e) {
					e.printStackTrace();
					logger.error("InterruptedException : save TAopLog error : ", e);
				}
			}
		}

	}

}
